package spe.ui.wizard;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;


public class DiagramNewWizardPage extends WizardPage
{
	public static final String PAGE_NAME = DiagramNewWizardPage.class.getName();
	
	private Text txtContainerFolder = null;
	private Text txtDiagramName = null;
	private Button browseButton;
	private String containerName;
	
	private IWorkspaceRoot workspaceRoot;
	
	protected DiagramNewWizardPage() 
	{
		super(PAGE_NAME);
		setTitle("Create New Method Plugin");
		setDescription("Create a new SPEM diagram");
		workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
	}
	
	public void init(IStructuredSelection selection)
	{
		IContainer container = null;
		
		if(selection != null)
		{
			Object object = selection.getFirstElement();
			if(IFile.class.isInstance(object) && !(IContainer.class.isInstance(object)))
				container = ((IFile)object).getParent();
			else
				if(IContainer.class.isInstance(object))
					container = (IContainer)object;
		}
		
		containerName = (container == null) ? "" : container.getFullPath().makeRelative().toString();
	}

	@Override
	public void createControl(Composite parent) 
	{
		initializeDialogUnits(parent);
		Composite content = createClientArea(parent);
		initControls(content);
		setControl(content);
		Dialog.applyDialogFont(content);
		setPageComplete(false);
	}

	private void initControls(Composite c)
	{
		
		//Set label
		Label label = new Label(c, SWT.WRAP);
		label.setText("Choose a source folder and enter name for new diagram.");
		GridData gd = new GridData();
		gd.widthHint = convertWidthInCharsToPixels(80);
		gd.horizontalSpan = 3;
		label.setLayoutData(gd);
		
		//Create container field
		label = new Label(c, SWT.NONE);
		label.setText("Source folder: ");
		txtContainerFolder = new Text(c, SWT.BORDER);
		txtContainerFolder.setText(containerName);
		txtContainerFolder.addModifyListener(new ModifyListener(){
			public void modifyText(ModifyEvent e)
			{
				verifyContentsValid();			
			}
		});
		gd = new GridData(GridData.FILL_HORIZONTAL);
		txtContainerFolder.setLayoutData(gd);
		
		browseButton = new Button(c, SWT.PUSH);
		browseButton.setText("Browse...");
		browseButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				chooseContainer();
			}			
		});
		gd = new GridData();
		gd.widthHint = convertWidthInCharsToPixels(15);
		browseButton.setLayoutData(gd);
		
		label = new Label(c, SWT.NONE);
		label.setText("Diagram name : ");
		txtDiagramName = new Text(c, SWT.BORDER);
		txtDiagramName.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				verifyContentsValid();
			}
		});
		gd = new GridData(GridData.FILL_HORIZONTAL);
		txtDiagramName.setLayoutData(gd);
	}
	
	private void chooseContainer() 
	{
		WorkbenchContentProvider provider= new WorkbenchContentProvider();
		ILabelProvider labelProvider= new WorkbenchLabelProvider(); 
		ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
		dialog.setTitle("Folder Selection");
		dialog.setMessage("Choose a folder");
		dialog.setInput(ResourcesPlugin.getWorkspace());
		dialog.addFilter(createViewerFilter());
		dialog.open();
		
		IContainer container = ((IContainer)dialog.getFirstResult());
		containerName = (container == null) ? "" : container.getFullPath().makeRelative().toString();
		txtContainerFolder.setText(containerName);
	}

	private Composite createClientArea(Composite parent)
	{
		Composite composite = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		layout.numColumns = 3;
		composite.setLayout(layout);
		
		return composite;
	}
	
	private void verifyContentsValid()
	{
		if (!checkContainerPathValid()) {
			setErrorMessage("The folder does not exist.");
			setPageComplete(false);
		} else if (isDiagramNameEmpty()) {
			setErrorMessage("Enter a name for the process.");
			setPageComplete(false);
		} else if (diagramExists()){
			setErrorMessage("A process with this name already exists.");
			setPageComplete(false);
		} else if(libraryNotExisted())
		{
			setErrorMessage("Method library is not existed in the folder.");
			setPageComplete(false);
		}else
		{
			setErrorMessage(null);
			setPageComplete(true);
		}
	}
	
	private boolean libraryNotExisted() 
	{
		IFolder folder = getLibraryFolder();
		IFile file = folder.getFile("spe-model.xml");
		return !(file.exists());
	}

	private ViewerFilter createViewerFilter() 
	{
		ViewerFilter filter= new ViewerFilter() {
			public boolean select(Viewer viewer, Object parent, Object element) {
				return IFolder.class.isInstance(element) || IProject.class.isInstance(element); 
			}
		};
		return filter;
	}
	
	private boolean diagramExists() 
	{
		IPath path = new Path(txtContainerFolder.getText()).append(txtDiagramName.getText());
		return workspaceRoot.getFile(path).exists();
	}
	
	private boolean isDiagramNameEmpty() 
	{
		String str = txtDiagramName.getText();
		return str == null || "".equals(str);
	}
	
	private boolean checkContainerPathValid() {
		if ("".equals(txtContainerFolder.getText())) {
			return false;
		}
		IPath path = new Path(txtContainerFolder.getText());
		return workspaceRoot.getFolder(path).exists();
	}
	
	@Override
	public boolean canFlipToNextPage()
	{
		if(getErrorMessage() != null)
			return false;
		return true;
	}
	
	public String getDiagramName()
	{
		return txtDiagramName.getText();
	}
	
	public IFolder getLibraryFolder()
	{
		IPath path = new Path(txtContainerFolder.getText());
		return workspaceRoot.getFolder(path);
	}
	
}
